#include "HttpServer.hpp"
#include "Err.hpp"
#include "Util.hpp"
#include <memory>
#include <vector>

const std::string SEP = "\r\n";

const std::string webRoot = "./wwwroot";
const std::string defaultHomePage = "index.html";
const std::string page_404 = "./wwwroot/err_404.html";

class HttpRequest
{
public:
    HttpRequest() : _path(webRoot)
    {}
    ~HttpRequest(){}

    void print()
    {
        logMessage(Debug, "method: %s, url: %s, version: %s",
        _method.c_str(), _url.c_str(), _httpVersion.c_str());   
        // for(const auto & line : _body)
        // {
        //     logMessage(Debug, "-%s", line.c_str());
        // }
        logMessage(Debug, "path: %s", _path.c_str());
        logMessage(Debug, "suffix: %s", _suffix.c_str());
    }
public:
    std::string _method;
    std::string _url;
    std::string _httpVersion;
    std::vector<std::string> _body;
    std::string _path;
    std::string _suffix;
};

HttpRequest Deserialize(std::string &message)
{
    HttpRequest req;
    std::string line = Util::ReadOneLine(message, SEP);//读取请求行
    Util::ParseRequestLine(line, &req._method, &req._url, &req._httpVersion);//解析请求行

    while (!message.empty())
    {
        line = Util::ReadOneLine(message, SEP);
        req._body.push_back(line);
    }
    req._path += req._url;
    if(req._path[req._path.size()-1] == '/')
    {
        req._path += defaultHomePage;
    }
    auto pos = req._path.rfind(".");
    if (pos == std::string::npos)
    {
        req._suffix = ".html"; 
    }
    else 
    {
        req._suffix = req._path.substr(pos);
    }
    return req;
}

std::string GetContentType(const std::string &suffix)
{
    std::string content_type = "Content-Type: ";
    if (suffix == ".html" || suffix == ".htm")
        content_type += "text/html";
    else if (suffix == ".css")
        content_type += "text/css";
    else if (suffix == ".js")
        content_type += "application/x-javascript";
    else if (suffix == ".png")
        content_type += "image/png";
    else if (suffix == ".jpg")
        content_type += "image/jpeg";
    else
    {
    }
    return content_type + SEP;
}

std::string handlerHttp(std::string &message)
{
    //读取请求
    //确信request是一个完整的http请求报文
    //给别人返回的是一个http response
    std::cout << "-------------------------------------" << std::endl;
    std::cout<< message << std::endl;

    //反序列化和分析请求
    HttpRequest req = Deserialize(message);
    req.print();
    //处理请求
    std::string body;
    std::string response;
    if (Util::ReadFile(req._path, &body) == true)
    {
        response = "HTTP/1.0 200 OK" + SEP;
        response += "Content-Length: " + std::to_string(body.size()) + SEP;
        response += GetContentType(req._suffix);
        response += SEP;
        response += body;
    }
    else
    {
        response = "HTTP/1.0 404 Not Found" + SEP;
        Util::ReadFile(page_404, &body);
        response += "Content-Length: " + std::to_string(body.size()) + SEP;
        response += GetContentType(".html");
        response += SEP;
        response += body;
    }

    // //重定向测试
    // std::string response;
    // response = "HTTP/1.0 302 Moved Permanently" + SEP;
    // response += "Location: https://www.baidu.com/" + SEP;
    // response += SEP;

    // //cookie && session id实验
    // std::string response;
    // response = "HTTP/1.0 200 OK" + SEP;
    // response += "Set-Cookie: sessionid=GY18" + SEP;
    // response += SEP;
    
    return response;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        exit(USAGE_ERR);
    }

    uint16_t port = atoi(argv[1]);
    std::unique_ptr<HttpServer> tsvr(new HttpServer(handlerHttp, port));
    tsvr->InitServer();
    tsvr->Start();

    return 0;
}